package com.smartlbs.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.sf.json.xml.XMLSerializer;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.smartlbs.baseframe.utils.WeChatUtils;
import com.smartlbs.dto.UserBasicDto;
import com.smartlbs.entity.PayLog;
import com.smartlbs.entity.SysUser;
import com.smartlbs.entity.UserBasic;
import com.smartlbs.enums.PayTypeEnums;
import com.smartlbs.enums.SettingEnums;
import com.smartlbs.mapper.PayLogMapper;
import com.smartlbs.mapper.UserBasicMapper;
import com.smartlbs.service.ISettingService;
import com.smartlbs.service.IUserBasicService;
import com.smartlbs.util.DESUtil;
import com.smartlbs.util.StringUtil;
import com.smartlbs.vo.UserBasicVo;

@Service("userBasicService")
public class UserBasicServiceImpl implements IUserBasicService {

	@Autowired
	private UserBasicMapper userBasicMapper;
	@Autowired
	private PayLogMapper payLogMapper;
	@Autowired
	private ISettingService settingService;
	
	@Override
	public UserBasic authLogin(String code,int os) throws Exception{
		//
		Map map = WeChatUtils.getOpenId(code,os);
		//
		String openId = map.get("openid")==null?"":map.get("openid").toString();
		if(StringUtil.containEmpty(openId)){
			return null;
		}
		//
		String accessToken = map.get("access_token")==null?"":map.get("access_token").toString();
		//换取用户信息，获取unionid
		Map userMap = WeChatUtils.getUserInfo(openId, accessToken);
		
		//
		UserBasic basic = new UserBasic();
		basic.setUnionid(userMap.get("unionid").toString());
		UserBasic userBasic = userBasicMapper.queryOne(basic);
		
		if(userBasic == null){
			//
			Integer sex = Integer.parseInt(userMap.get("sex").toString());
			String nickname=userMap.get("nickname")==null?"":userMap.get("nickname").toString();
			String headPhoto = userMap.get("headimgurl")==null?"":userMap.get("headimgurl").toString();
			userBasic = new UserBasic();
			userBasic.setCreateTime(new Date());
			userBasic.setOpenId(openId);
			userBasic.setUnionid(userMap.get("unionid").toString());
			userBasic.setLastLogin(DateUtils.round(new Date(), Calendar.SECOND));
			//EmojiParser.parseToAliases(nickName);
			userBasic.setNickname(URLEncoder.encode(nickname, "utf-8"));
			userBasic.setHeadPhoto(headPhoto);
			userBasic.setSex(sex);
			userBasic.setPoints("0");
			
			userBasicMapper.insert(userBasic);
		}else{
			userBasic.setLastLogin(DateUtils.round(new Date(), Calendar.SECOND));
			userBasic.setOpenId(openId);
			//
			userBasicMapper.update(userBasic);
		}
		
		//解密昵称
		userBasic.setNickname(URLDecoder.decode(userBasic.getNickname(), "utf-8"));
		return userBasic;
	}
	
	@Override
	public UserBasic findById(Long userId) throws Exception {
		UserBasic userBasic = userBasicMapper.findById(userId);
		
		if(userBasic != null && !StringUtil.containEmpty(userBasic.getNickname())){
			userBasic.setNickname(URLDecoder.decode(userBasic.getNickname(), "utf-8"));
		}
		
		return userBasic;
	}
	
	@Override
	public void callBack(String message) throws Exception {
		XMLSerializer xmlSerializer = new XMLSerializer();  
        net.sf.json.JSON jsonObj = xmlSerializer.read(message);  
        String jsonStr = jsonObj.toString();
		//
		Map callBackMap = JSON.parseObject(jsonStr, Map.class);
		//
		String returnCode = callBackMap.get("return_code")==null?"":callBackMap.get("return_code").toString();
		//
		if(!StringUtil.containEmpty(returnCode) && returnCode.equals("SUCCESS")){
			//微信支付流水
			String transaction_id = callBackMap.get("transaction_id")==null?"":callBackMap.get("transaction_id").toString();
			//格式uid-随机数
			String outTradeNo = callBackMap.get("out_trade_no")==null?"":callBackMap.get("out_trade_no").toString();
			//支付金额
			Double points = Double.parseDouble(callBackMap.get("cash_fee").toString())/100;
			//用户id
			long userId = StringUtil.getLong(outTradeNo.split("-")[0], 0);
			
			//充值配置
			Map<String, String> map = settingService.getSetting(String.valueOf(SettingEnums.VOUCHER.getValue()));
			String str = map.get(SettingEnums.VOUCHER.getMemo());
			List<Map> list = JSON.parseArray(str, Map.class);
			
			//奖励积分
			long grant = 0;
			for(Map ins:list){
				//
				Double payPoints = StringUtil.getDouble(ins.get("points"), 0);
				
				if(Double.doubleToLongBits(points) == Double.doubleToLongBits(payPoints)){
					grant = StringUtil.getLong(ins.get("award"), 0);
					break;
				}
			}
			
			//变更用户积分
			UserBasic userBasic = userBasicMapper.findById(userId);
			BigDecimal oldPoints = new BigDecimal(userBasic.getPoints());
			BigDecimal addPoints = new BigDecimal(String.valueOf(points+grant));
			BigDecimal sumPoints = oldPoints.add(addPoints);
			
			userBasic = new UserBasic();
			userBasic.setUserId(userId);
			userBasic.setPoints(sumPoints.toString());
			userBasicMapper.update(userBasic);
			
			//变更充值流水
			PayLog payLog = new PayLog();
			
			payLog.setUserId(userId);
			payLog.setType(PayTypeEnums.VOUCHER.getValue());
			payLog.setPoints(String.valueOf(points));
			payLog.setCreateTime(new Date());
			payLog.setAdminId(0L);
			payLog.setOutId(transaction_id);
			payLogMapper.insert(payLog);
			
			//有奖励
			if(grant > 0){
				//
				PayLog payLog2 = new PayLog();
				
				payLog2.setUserId(userId);
				payLog2.setType(PayTypeEnums.AWARD.getValue());
				payLog2.setPoints(String.valueOf(grant));
				payLog2.setCreateTime(new Date());
				payLog2.setAdminId(0L);
				payLog.setOutId(transaction_id);
				
				payLogMapper.insert(payLog2);
			}
		}
	}
	
	@Override
	public void updateSessionId(Long userId, String sessionId) {
		/*
		 * 用户基本信息实体类
		 */
		UserBasic userBasic = new UserBasic();
		
		userBasic.setUserId(userId);
		userBasic.setSessionId(sessionId);
		
		userBasicMapper.update(userBasic);
	}
	
	@Override
	public UserBasicVo getUserInfo(Long userId) {
		//
		UserBasic userBasic = userBasicMapper.findById(userId);
		
		UserBasicVo userBasicVo = new UserBasicVo();
		
		try {
			//
			if(userBasic != null && !StringUtil.containEmpty(userBasic.getNickname())){
				userBasic.setNickname(URLDecoder.decode(userBasic.getNickname(), "utf-8"));
			}
			BeanUtils.copyProperties(userBasicVo, userBasic);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return userBasicVo;
	}
	
	@Override
	public PageInfo<UserBasic> find(Integer pageNum, Integer pageSize,
			UserBasicDto userBasicDto) {
		Page<UserBasic> page = PageHelper.startPage(pageNum, pageSize);
		
		List<UserBasic> userBasicList = userBasicMapper.find(userBasicDto);
		
		PageInfo<UserBasic> pageInfo = page.toPageInfo();
		//
		List<UserBasicVo> userBasicVoList = new ArrayList<>();
		
		if(userBasicList != null && userBasicList.size() > 0){
			for(UserBasic userBasic:userBasicList){
				try {
					//
					if(!StringUtil.containEmpty(userBasic.getNickname())){
						userBasic.setNickname(URLDecoder.decode(userBasic.getNickname(), "utf-8"));
					}
					//
					UserBasicVo userBasicVo = new UserBasicVo();
					BeanUtils.copyProperties(userBasicVo, userBasic);
					//
					userBasicVoList.add(userBasicVo);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		
		pageInfo.getList().removeAll(pageInfo.getList());
		pageInfo.getList().addAll(userBasicVoList);
		
		return pageInfo;
	}
	
	private static String filterEmoji(String nickName) {
		//nick_name 所获取的用户昵称 
		if (nickName == null || "".equals(nickName)) {
			return nickName;
		}
		Pattern emoji = Pattern.compile("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]",
				Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
		//
		Matcher emojiMatcher = emoji.matcher(nickName);
		
		if (emojiMatcher.find()) {
			//将所获取的表情转换为*
			nickName = emojiMatcher.replaceAll("*");
			return nickName;
		}
		System.out.println(nickName);
		return nickName;
	}

	@Override
	public String updatePoints(SysUser user, Long userId, Double points) {
		// TODO Auto-generated method stub
		
		//记录变更流水
		PayLog payLog = new PayLog();
		
		payLog.setCreateTime(new Date());
		payLog.setUserId(userId);
		payLog.setPoints(points+"");
		payLog.setType(PayTypeEnums.AWARD.getValue());
		payLog.setAdminId(user.getAdminId());
		payLog.setOutId("0");
		//流水增加成功再实际变更用户积分
		if(payLogMapper.insert(payLog)>0){
			
			//给用户变更积分
			BigDecimal decimal = new BigDecimal(userBasicMapper.findById(userId).getPoints()).add(new BigDecimal(points)).setScale(2, RoundingMode.HALF_UP);
			//
			UserBasic basic = new UserBasic();
			basic.setUserId(userId);
			basic.setPoints(decimal.toString());
			userBasicMapper.update(basic);
			
			return decimal.toString();
		}
		return "";
	}

	@Override
	public int update(UserBasic userBasic) {
		// TODO Auto-generated method stub
		return	userBasicMapper.update(userBasic);
	}
}